package main

import (
	"MyBlogv2/common/crawler"
	"MyBlogv2/common/milvus"
	"MyBlogv2/common/models"
	"fmt"
	"log"
	"time"
)

func main2(){
	// 选择要执行的功能
	// 1. 爬取新文章并保存到数据库
	crawlerByKeywords()
	
	// 2. 同步现有文章到 Milvus
	// syncArticlesToNeo4jAndMilvus()
}


// syncArticlesToNeo4jAndMilvus 将数据库中的文章同步到Milvus
func syncArticlesToNeo4jAndMilvus() {
	fmt.Println("========================================")
	fmt.Println("开始同步文章到Milvus")
	fmt.Println("========================================")
	
	// 查询数据库中所有文章
	var articles []models.Article
	result := models.Db.Where("is_deleted = ? AND status = ? AND id > 311", 0, 1).Find(&articles)
	if result.Error != nil {
		log.Printf("❌ 查询文章失败: %v", result.Error)
		return
	}
	
	totalCount := len(articles)
	fmt.Printf("📊 数据库中共有 %d 篇文章\n\n", totalCount)
	
	if totalCount == 0 {
		fmt.Println("⚠️  没有需要同步的文章")
		return
	}
	
	// 统计信息
	successCount := 0
	skipCount := 0
	failCount := 0
	
	// 遍历所有文章，同步到Milvus
	for i, article := range articles {
		fmt.Printf("[%d/%d] 处理文章ID: %d, 标题: %s\n", i+1, totalCount, article.Id, article.ArticleTitle)
		
		// 检查是否已存在于Milvus中
		count, err := milvus.MilvusDB.GetCountByPostID(int64(article.Id))
		if err != nil {
			log.Printf("   ❌ 检查Milvus失败: %v", err)
			failCount++
			continue
		}
		
		if count > 0 {
			fmt.Printf("   ⏭️  已存在于Milvus中，跳过\n")
			skipCount++
			continue
		}
		
		// 插入到Milvus
		err = milvus.MilvusDB.UpsertArticleToMilvus(article)
		if err != nil {
			log.Printf("   ❌ 插入Milvus失败: %v", err)
			failCount++
		} else {
			fmt.Printf("   ✅ 成功插入Milvus\n")
			successCount++
		}
		
		// 添加短暂延迟
		if i < totalCount-1 {
			time.Sleep(100 * time.Millisecond)
		}
	}
	
	// 输出统计信息
	fmt.Println("\n========================================")
	fmt.Println("同步完成！")
	fmt.Printf("总计文章: %d 篇\n", totalCount)
	fmt.Printf("✅ 成功插入: %d 篇\n", successCount)
	fmt.Printf("⏭️  已存在跳过: %d 篇\n", skipCount)
	fmt.Printf("❌ 失败: %d 篇\n", failCount)
	fmt.Println("========================================")
}

func crawlerByKeywords() {
	// 创建爬虫实例
	c := crawler.NewCSDNCrawler()
	
	// 定义关键词数组
	keywords := []string{
		// "Go语言",
		// "Python",
		// "Java",
		"JavaScript",
		"C++",
		"数据结构",
		"算法",
		"机器学习",
		"深度学习",
		"前端开发",
		// 可以继续添加更多关键词...
		"Docker",
		"Kubernetes",
		"微服务",
		"区块链",
		"人工智能",
	}
	
	// 每个关键词搜索的文章数量
	maxResults := 8
	
	fmt.Printf("开始批量搜索并保存到数据库，共 %d 个关键词，每个关键词获取 %d 篇文章\n", len(keywords), maxResults)
	fmt.Println("========================================")
	
	// 存储所有结果的统计信息
	totalArticles := 0
	successCount := 0
	failCount := 0
	
	// 遍历每个关键词进行搜索
	for i, keyword := range keywords {
		fmt.Printf("\n[%d/%d] 正在搜索关键词: %s\n", i+1, len(keywords), keyword)
		
		// 搜索文章
		results, err := c.SearchArticles(keyword, maxResults)
		if err != nil {
			log.Printf("❌ 搜索失败: %v", err)
			failCount++
			continue
		}
		
		// 统计结果
		successCount++
		totalArticles += len(results)
		fmt.Printf("✅ 成功获取 %d 篇文章\n", len(results))
		
		// 显示前3篇文章作为示例
		fmt.Println("   前3篇示例:")
		displayCount := 3
		if len(results) < displayCount {
			displayCount = len(results)
		}
		for j := 0; j < displayCount; j++ {
			fmt.Printf("   [%d] %s (作者: %s)\n", j+1, results[j].Title, results[j].Author)
		}
		
		// 保存文章到数据库
		fmt.Printf("   💾 开始保存到数据库...\n")
		savedCount, failedCount := saveArticlesToDatabase(c, keyword, results)
		fmt.Printf("   ✅ 成功保存 %d 篇，失败 %d 篇\n", savedCount, failedCount)
		
		// 添加延迟，避免请求过于频繁
		if i < len(keywords)-1 {
			fmt.Println("   等待1秒后继续...")
			time.Sleep(1 * time.Second)
		}
	}
	
	// 输出统计信息
	fmt.Println("\n========================================")
	fmt.Println("搜索完成！")
	fmt.Printf("总计关键词: %d 个\n", len(keywords))
	fmt.Printf("成功: %d 个\n", successCount)
	fmt.Printf("失败: %d 个\n", failCount)
	fmt.Printf("总共获取文章: %d 篇\n", totalArticles)
	fmt.Println("========================================")
}

// saveArticlesToDatabase 保存文章到数据库
func saveArticlesToDatabase(c *crawler.CSDNCrawler, categoryName string, results []crawler.SearchResult) (int, int) {
	savedCount := 0
	failedCount := 0
	
	for i, result := range results {
		fmt.Printf("   [%d/%d] 正在爬取: %s\n", i+1, len(results), result.Title)
		
		// 调用爬虫保存到数据库
		err := c.CrawlAndSaveToDatabaseWithUrlAndCategoryName(result.URL, categoryName)
		if err != nil {
			log.Printf("      ❌ 保存失败: %v", err)
			failedCount++
		} else {
			fmt.Printf("      ✅ 保存成功\n")
			savedCount++
		}
		
		// 每篇文章之间添加短暂延迟，避免请求过快
		if i < len(results)-1 {
			time.Sleep(500 * time.Millisecond)
		}
	}
	
	return savedCount, failedCount
}